﻿using System;
using System.Collections.Generic;
using System.Text;
using TCCUIControls;
using TCCHWLib.Commands;
using System.Windows.Forms;

namespace TCCHWLib
{
    /// <summary>
    /// Hardware Chip. Use 'Chip.Instance' to access the singleton instance 
    /// </summary>
    public class Chip
    {
        #region Singleton Code
        private static Chip m_Chip = null;
        public static Chip Instance
        {
            get
            {
                if (m_Chip == null)
                    m_Chip = new Chip();

                return Chip.m_Chip;
            }
            set { Chip.m_Chip = value; }
        }
        #endregion

        private Memory m_SharedMemory = null;
        private List<Processor> m_ProcessorsList = null;
        private CommitArbiter m_Arbiter = null;
        private CommunicationBus m_Bus = null;
        private UIChip m_UiChip = null;
        private Random m_Random;
        private bool m_IsManuallyControlled = true;

        public bool IsManuallyControlled
        {
            get { return m_IsManuallyControlled; }
            set { m_IsManuallyControlled = value; }
        }

        public Random Random
        {
            get { return m_Random; }
            set { m_Random = value; }
        }

        public UIChip UiChip
        {
            get { return m_UiChip; }
            set { m_UiChip = value; }
        }

        public CommunicationBus Bus
        {
            get { return m_Bus; }
            set { m_Bus = value; }
        }
        public Memory SharedMemory
        {
            get { return m_SharedMemory; }
            set { m_SharedMemory = value; }
        }
        public CommitArbiter Arbiter
        {
            get { return m_Arbiter; }
            set { m_Arbiter = value; }
        }
        public List<Processor> Processors
        {
            get { return m_ProcessorsList; }
            set { m_ProcessorsList = value; }
        }

        private Chip()
        {
            m_ProcessorsList = new List<Processor>();

            m_UiChip = new UIChip();
        }

        public void ConstructChip()
        {
            List<UserControl> uiControls = new List<UserControl>();

            m_Random = new Random(DateTime.Now.Millisecond);

            // Create a communication bus
            m_Bus = new CommunicationBus();

            // Create a central task commit arbiter
            m_Arbiter = new CommitArbiter();
            uiControls.Add(m_Arbiter.UIArbiter);
            
            // Create a shared memory & attach it to the bus
            m_SharedMemory = new Memory(Configuration.Instance.SharedMemorySize);
            m_Bus.SharedMemory = m_SharedMemory;

            uiControls.Add(m_SharedMemory.UISharedMemory);

            // Create n-processors & attach them to the bus
            Processor processor;
            for (int i = 0; i < Configuration.Instance.ProcessorsCount; i++)
            {
                processor = new Processor("Processor_" + (i + 1), Configuration.Instance.DefaultCacheSize);
                m_ProcessorsList.Add(processor);
                m_Bus.Attach(processor);
                uiControls.Add(processor.UiProcessor);
            }

            m_UiChip.InitializeUI(uiControls);
        }

        public static void WriteToConsole(string str)
        {
            UIArbiter.WriteToConsole(str);
        }
    }
}
